﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CallTimingAnalysis
{
    public partial class GroupView : Form
    {
        public List<LogEntity> Entites { get; set; }
        public GroupView()
        {
            InitializeComponent();
        }

        private void GroupView_Load(object sender, EventArgs e)
        {
            this.txtMinLimit.Text = "0";
            this.cbo_page.SelectedIndexChanged += cbo_page_SelectedIndexChanged;

            this.dgv_source.RowsDefaultCellStyle.Font = new Font("微软雅黑", 14);
            this.dgv_source.RowsDefaultCellStyle.ForeColor = Color.Gray;
            this.dgv_source.RowTemplate.Height = 28;
            this.dgv_source.AllowUserToOrderColumns = true;
            this.dgv_source.DataError += (obj, ea) => { };
            this.dgv_source.SelectionChanged += dgv_source_SelectionChanged;

            this.dataGridView1.RowHeadersVisible = false;
            this.dataGridView1.AutoGenerateColumns = true;
            this.label1.Visible = !this.label1.Visible;

            this.cbo_orderby.SelectedIndex = 3;
        }
        void dgv_source_SelectionChanged(object sender, EventArgs e)
        {
            var row = this.dgv_source.CurrentRow;
            if (row == null)
                return;
            var log = row.DataBoundItem as LogEntity;
            if (log == null)
                return;
            this.dataGridView1.DataSource = log.Items;
            this.Text = log.Page;
        }

        void cbo_page_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.cbo_cout.Items.Clear();
            var selectedItem = cbo_page.SelectedItem as CBOPageItem;
            if (selectedItem == null)
            {
                return;
            }
            this.cbo_cout.Items.Add(new CBOPageItem() { count = -1, name = "ALL" });
            if (selectedItem.count > 10000)
            {
                var c5 = selectedItem.count / 10000;

                for (int i = 0; i < c5; i++)
                {
                    this.cbo_cout.Items.Add(new CBOPageItem()
                    {
                        count = (i + 1) * 10000,
                        name = ((i + 1) * 10000).ToString()
                    });
                }
            }

            this.cbo_cout.SelectedIndex = 0;
        }
        Stopwatch sw = new Stopwatch();
        IGrouping<string, LogEntity>[] _filterData;
        List<LogEntity> _searchData;

        //初始化
        private async void button2_Click(object sender, EventArgs e)
        {
            var filterC = int.Parse(this.txtMinLimit.Text.Trim());
            sw.Start();
            this.label1.Visible = !this.label1.Visible;
            this.button2.Enabled = false;

            this.label1.Text = "预初始化数据，for循环集合";
            await Task.Run(() =>
            {
                Entites
                    .AsParallel()
                    .WithDegreeOfParallelism(8)
                    .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                    .ForAll(p =>
                //.ForEach(p =>
                {
                    var x = p.Timing;
                    var xxx = p.Page;
                    var xx = p.PageName;

                });
            });
            var pageList =
                await Task.Run(() =>
                {
                    this.label1.Text = "预初始化数据，生成分组数据";
                    var q = Entites.AsParallel();
                    if (filterC > 0)
                        q = q.Where(p => p.Timing > filterC);

                    _filterData = q.GroupBy(p => p.PageName, new eq())
                        .ToArray();
                    this.label1.Text = "预初始化数据，生成分统计组数据";
                    return _filterData
                          .Select(p => new CBOPageItem { name = p.Key, count = p.Count() })
                          .OrderByDescending(p => p.count)
                          .ToList();
                });
            pageList.Insert(0, new CBOPageItem() { count = -1, name = "ALL" });
            this.cbo_page.DataSource = pageList;

            this.cbo_page.DropDownStyle = ComboBoxStyle.DropDownList;
            this.cbo_cout.DropDownStyle = ComboBoxStyle.DropDownList;
            this.cbo_orderby.DropDownStyle = ComboBoxStyle.DropDownList;
            this.button2.Enabled = true;
            this.Text = "初始化完成，耗时：" + sw.ElapsedMilliseconds;
            this.label1.Visible = !this.label1.Visible;
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            sw.Restart();
            this.label1.Visible = !this.label1.Visible;
            this.Text = "开始生成数据。。。。。。。";
            this.button1.Enabled = false;
            this.dgv_source.DataSource = await Task.Run(() =>
            {
                _searchData = GetLogs()
                    //.AsParallel()
                    .ToList();

                return _searchData.ToBindingList();
            });
            var width = this.dgv_source.Width - 20;
            this.dgv_source.Columns["ItemsStr"].Visible = false;
            this.dgv_source.Columns["Page"].Visible = false;
            //if (width <= 800)
            {
                this.dgv_source.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
                foreach (DataGridViewColumn item in dgv_source.Columns)
                {
                    if (!item.Visible)
                    {
                        continue;
                    }
                    item.Width = 160;
                }
                dgv_source.Columns["Page"].Width = width - (160 * 4);
            }
            this.button1.Enabled = true;
            this.label1.Visible = !this.label1.Visible;
            this.Text = "数据查询完成，耗时：" + sw.ElapsedMilliseconds;
        }
        //根据条件，生成数据
        private IEnumerable<LogEntity> GetLogs()
        {
            var filterC = int.Parse(this.txtMinLimit.Text.Trim());
            var pageItem = this.cbo_page.SelectedItem as CBOPageItem;
            var countItem = this.cbo_cout.SelectedItem as CBOPageItem;
            var orderByItem = this.cbo_orderby.SelectedIndex;

            if (pageItem == null || countItem == null || orderByItem < 0)
            {
                return null;
            }
            IEnumerable<LogEntity> data = null;

            if (pageItem.count == -1)
                data = this.Entites.Where(p => p.Timing > filterC);
            else
                data = this._filterData.First(p => p.Key == pageItem.name);

            switch (orderByItem)
            {
                //请选择
                //时间
                //页面名称
                //耗时
                case 1:
                    data = data.OrderByDescending(p => p.Date);
                    break;
                case 2:
                    data = data.OrderByDescending(p => p.PageName);
                    break;
                case 3:
                    data = data.OrderByDescending(p => p.Timing);
                    break;
            }

            if (countItem.count != -1)
                data = data.Take(countItem.count);
            return data;
        }

        private async void button3_Click(object sender, EventArgs e)
        {
            int timing = this.txt_value.Text.Trim().ToInt();
            string key = this.txt_name.Text.Trim();
            var hasCK = !this.txt_value.Text.IsNullOrEmpty();
            var hasNK = !this.txt_NK.Text.IsNullOrEmpty();
            var NKKey = this.txt_NK.Text.Trim();
            this.dgv_source.DataSource = await Task.Run(() =>
            {
                return _searchData.Where(p =>
                     {
                         if (hasNK)
                         {
                             if (p.Items.Any(pp => pp.Key == NKKey))
                             {
                                 return false;
                             }
                         }
                         if (hasCK)
                         {
                             return p.Items.Any(pp => pp.Key == key && pp.Timing > timing);
                         }
                         return true;

                     })
                     .ToList().ToBindingList();
            });
        }
    }
    public class CBOPageItem
    {
        public string name { get; set; }
        public int count { get; set; }
        public override string ToString()
        {
            return this.name + "-" + this.count;
        }
    }

    public class eq : IEqualityComparer<string>
    {

        public bool Equals(string x, string y)
        {
            return String.Equals(x, y, StringComparison.OrdinalIgnoreCase);
        }

        public int GetHashCode(string obj)
        {
            return 0;
        }
    }
}
